package com.sushi.bigblog.web.service;

import com.sushi.bigblog.filedb.Db;
import com.sushi.bigblog.filedb.DbEntry;
import com.sushi.bigblog.utils.LRUCache;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 * User: bianpeng
 * Date: 11-12-3
 */
@Component
public class BlogService {
    @Value("#{app.save_directory}")
    private String saveDirectory;

    public static class Blog {
        private DbEntry entry;
        byte[] content;

        public byte[] getContent() {
            return content;
        }
        public long getId() {
            return entry.getOffset();
        }

        public boolean isGZipped() {
            return (entry.getFlag() & Db.FLAG_GZIPPED) != 0;
        }
    }
    private Logger logger = Logger.getLogger(getClass());

    private LRUCache<Long, Blog> cache = new LRUCache<Long, Blog>(20);
    private Db db;

    @PostConstruct
    public void init() {
        try {
            db = new Db(new File(saveDirectory + "/bianp.idx"), new File(saveDirectory + "/bianp.idb"));
        } catch (IOException e) {
            logger.error("open blog db failed", e);
        }
    }

    @PreDestroy
    public void destroy() {
        try {
            db.close();
        } catch (IOException e) {
            logger.error("close db failed", e);
        }
    }

    public Blog getBlog(long id) throws IOException {
        Blog blog = cache.get(id);
        if (blog != null) return blog;
        synchronized (db) {
            DbEntry entry = db.findBlog(id);
            if (entry != null) {
                blog = new Blog();
                blog.entry = entry;
                blog.content = db.loadContent(entry);
                cache.put(id, blog);
                return blog;
            }
        }
        return null;
    }

    public synchronized long saveBlog(byte[] content, int owner, int flag) {
        Blog blog = new Blog();
        try {
            blog.entry = db.appendContent(content, owner, flag);
        } catch (IOException e) {
            logger.error("save blog failed", e);
        }
        blog.content = content;
        long id = blog.getId();
        cache.put(id, blog);
        return id;
    }

    /**
     *
     * @param offset 倒数的offset
     * @param limit 取出来的数量
     * @return
     */
    public List<DbEntry> getEntryList(int offset, int limit) throws IOException {
        List<DbEntry> entries = db.getEntryList(offset, limit);
        return entries;
    }
}
